//! 集合操作工具

use std::collections::{HashMap, HashSet};
use std::hash::Hash;

/// 查找两个集合的交集
/// 
/// # 示例
/// 
/// ```
/// use rust_utils::collection_utils::intersection;
/// use std::collections::HashSet;
/// 
/// let set1: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
/// let set2: HashSet<i32> = [2, 3, 4].iter().cloned().collect();
/// let result = intersection(&set1, &set2);
/// let expected: HashSet<i32> = [2, 3].iter().cloned().collect();
/// assert_eq!(result, expected);
/// ```
pub fn intersection<T>(set1: &HashSet<T>, set2: &HashSet<T>) -> HashSet<T>
where
    T: Clone + Eq + Hash,
{
    set1.intersection(set2).cloned().collect()
}

/// 查找两个集合的并集
/// 
/// # 示例
/// 
/// ```
/// use rust_utils::collection_utils::union;
/// use std::collections::HashSet;
/// 
/// let set1: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
/// let set2: HashSet<i32> = [2, 3, 4].iter().cloned().collect();
/// let result = union(&set1, &set2);
/// let expected: HashSet<i32> = [1, 2, 3, 4].iter().cloned().collect();
/// assert_eq!(result, expected);
/// ```
pub fn union<T>(set1: &HashSet<T>, set2: &HashSet<T>) -> HashSet<T>
where
    T: Clone + Eq + Hash,
{
    set1.union(set2).cloned().collect()
}

/// 查找两个集合的差集
/// 
/// # 示例
/// 
/// ```
/// use rust_utils::collection_utils::difference;
/// use std::collections::HashSet;
/// 
/// let set1: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
/// let set2: HashSet<i32> = [2, 3, 4].iter().cloned().collect();
/// let result = difference(&set1, &set2);
/// let expected: HashSet<i32> = [1].iter().cloned().collect();
/// assert_eq!(result, expected);
/// ```
pub fn difference<T>(set1: &HashSet<T>, set2: &HashSet<T>) -> HashSet<T>
where
    T: Clone + Eq + Hash,
{
    set1.difference(set2).cloned().collect()
}

/// 将Vec转换为HashSet
/// 
/// # 示例
/// 
/// ```
/// use rust_utils::collection_utils::vec_to_hashset;
/// use std::collections::HashSet;
/// 
/// let vec = vec![1, 2, 2, 3, 3, 3];
/// let set: HashSet<i32> = vec_to_hashset(vec);
/// assert_eq!(set.len(), 3);
/// ```
pub fn vec_to_hashset<T>(vec: Vec<T>) -> HashSet<T>
where
    T: Eq + Hash,
{
    vec.into_iter().collect()
}

/// 合并两个HashMap
/// 
/// # 示例
/// 
/// ```
/// use rust_utils::collection_utils::merge_hashmap;
/// use std::collections::HashMap;
/// 
/// let mut map1 = HashMap::new();
/// map1.insert("a", 1);
/// map1.insert("b", 2);
/// 
/// let mut map2 = HashMap::new();
/// map2.insert("b", 3);
/// map2.insert("c", 4);
/// 
/// let merged = merge_hashmap(&map1, &map2);
/// assert_eq!(merged.get("a"), Some(&1));
/// assert_eq!(merged.get("b"), Some(&3)); // map2的值会覆盖map1的值
/// assert_eq!(merged.get("c"), Some(&4));
/// ```
pub fn merge_hashmap<K, V>(map1: &HashMap<K, V>, map2: &HashMap<K, V>) -> HashMap<K, V>
where
    K: Clone + Eq + Hash,
    V: Clone,
{
    let mut result = map1.clone();
    for (key, value) in map2 {
        result.insert(key.clone(), value.clone());
    }
    result
}

/// 查找Vec中的重复元素
/// 
/// # 示例
/// 
/// ```
/// use rust_utils::collection_utils::find_duplicates;
/// 
/// let vec = vec![1, 2, 2, 3, 3, 3, 4];
/// let duplicates = find_duplicates(&vec);
/// assert!(duplicates.contains(&&2));
/// assert!(duplicates.contains(&&3));
/// assert!(!duplicates.contains(&&1));
/// assert!(!duplicates.contains(&&4));
/// ```
pub fn find_duplicates<T>(vec: &[T]) -> Vec<&T>
where
    T: Eq + Hash,
{
    let mut seen = HashSet::new();
    let mut duplicates = Vec::new();
    
    for item in vec {
        if !seen.insert(item) && !duplicates.contains(&item) {
            duplicates.push(item);
        }
    }
    
    duplicates
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::HashMap;

    #[test]
    fn test_intersection() {
        let set1: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
        let set2: HashSet<i32> = [2, 3, 4].iter().cloned().collect();
        let result = intersection(&set1, &set2);
        let expected: HashSet<i32> = [2, 3].iter().cloned().collect();
        assert_eq!(result, expected);
    }

    #[test]
    fn test_union() {
        let set1: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
        let set2: HashSet<i32> = [2, 3, 4].iter().cloned().collect();
        let result = union(&set1, &set2);
        let expected: HashSet<i32> = [1, 2, 3, 4].iter().cloned().collect();
        assert_eq!(result, expected);
    }

    #[test]
    fn test_difference() {
        let set1: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
        let set2: HashSet<i32> = [2, 3, 4].iter().cloned().collect();
        let result = difference(&set1, &set2);
        let expected: HashSet<i32> = [1].iter().cloned().collect();
        assert_eq!(result, expected);
    }

    #[test]
    fn test_vec_to_hashset() {
        let vec = vec![1, 2, 2, 3, 3, 3];
        let set: HashSet<i32> = vec_to_hashset(vec);
        assert_eq!(set.len(), 3);
    }

    #[test]
    fn test_merge_hashmap() {
        let mut map1 = HashMap::new();
        map1.insert("a", 1);
        map1.insert("b", 2);

        let mut map2 = HashMap::new();
        map2.insert("b", 3);
        map2.insert("c", 4);

        let merged = merge_hashmap(&map1, &map2);
        assert_eq!(merged.get("a"), Some(&1));
        assert_eq!(merged.get("b"), Some(&3)); // map2的值会覆盖map1的值
        assert_eq!(merged.get("c"), Some(&4));
    }

    #[test]
    fn test_find_duplicates() {
        let vec = vec![1, 2, 2, 3, 3, 3, 4];
        let duplicates = find_duplicates(&vec);
        assert!(duplicates.contains(&&2));
        assert!(duplicates.contains(&&3));
        assert!(!duplicates.contains(&&1));
        assert!(!duplicates.contains(&&4));
    }
}